<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Home - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Constants.html">Constants</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Extension.html">Extension</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ExtensionAction.html">ExtensionAction</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="FrameworkState.html">FrameworkState</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Minima.html">Minima</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.addService">addService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getDefaultService">getDefaultService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getExtensions">getExtensions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getPlugin">getPlugin</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getPlugin">getPlugin</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getPlugins">getPlugins</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getPlugins">getPlugins</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.getServices">getServices</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.removeService">removeService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.start">start</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Minima.html#.stop">stop</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Plugin.html">Plugin</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.assertResolved">assertResolved</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.assertUninstalled">assertUninstalled</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.doStart">doStart</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.doStop">doStop</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.loadClass">loadClass</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.resolveActivator">resolveActivator</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.start">start</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.stop">stop</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Plugin.html#.uninstall">uninstall</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="PluginConfiguration.html">PluginConfiguration</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginConfiguration.html#.parseBasic">parseBasic</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginConfiguration.html#.parseDependencies">parseDependencies</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginConfiguration.html#.parseExtensions">parseExtensions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginConfiguration.html#.parseServices">parseServices</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="PluginContext.html">PluginContext</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addExtension">addExtension</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addExtensionChangedListener">addExtensionChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addExtensionChangedListener">addExtensionChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addFrameworkStateChangedListener">addFrameworkStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addPluginStateChangedListener">addPluginStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addPluginStateChangedListener">addPluginStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addService">addService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addServiceChangedListener">addServiceChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.addServiceChangedListener">addServiceChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.dispose">dispose</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.getDefaultService">getDefaultService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.getExtensions">getExtensions</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.getServices">getServices</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.installPlugin">installPlugin</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeExtension">removeExtension</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeExtensionChangedListener">removeExtensionChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeExtensionChangedListener">removeExtensionChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeFrameworkStateChangedListener">removeFrameworkStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removePluginStateChangedListener">removePluginStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removePluginStateChangedListener">removePluginStateChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeService">removeService</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeServiceChangedListener">removeServiceChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.removeServiceChangedListener">removeServiceChangedListener</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.start">start</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginContext.html#.stop">stop</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="PluginMetadata.html">PluginMetadata</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginMetadata.html#.markFailed">markFailed</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginMetadata.html#.markResolvable">markResolvable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="PluginMetadata.html#.markSuccess">markSuccess</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="PluginState.html">PluginState</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ResolveState.html">ResolveState</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ServiceAction.html">ServiceAction</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ServiceRegistry.html">ServiceRegistry</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="Version.html">Version</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Version.html#.compare">compare</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="Version.html#.parse">parse</a></span></li>
</nav>

<div id="main">
    

    



    









    


    <section class="readme">
        <article><h1>minimajs</h1><p>Minima is a simple yet powerfully plugin framework, based on NodeJS, developed by ES6.</p>
<p>There are three features:
(1) Dynamic plugin: define the plugin structure, plugin config, plugin dependencies, plugin lifecycle, plugin class loading;
(2) Service: the communication between plugins with SOA;
(3) Extension: the extension supporting for plugin.</p>
<h2>Install</h2><p>Install with <a href="https://www.npmjs.com/">npm</a>:</p>
<pre class="prettyprint source lang-sh"><code>$ npm install --save minimajs</code></pre><h2>Usage</h2><p>The Minima is a plugin framework container. We need to create a plugin framework instance and start it.</p>
<pre class="prettyprint source lang-js"><code>import { Minima } from 'minimajs';

let minima = new Minima(__dirname + '/plugins');
minima.start();</code></pre><p><strong>Examples</strong></p>
<p>Create a simple plugin in plugins directory as below.</p>
<pre class="prettyprint source lang-js"><code>// 1 plugin.json
{
    &quot;id&quot;: &quot;demoPlugin&quot;,
    &quot;startLevel&quot;: 3,
    &quot;version&quot;: &quot;1.0.0&quot;
}
// 2 Activator.js
import { ServiceAction, ExtensionAction, PluginContext, Plugin, log } from 'minimajs';

export default class Activator {
    /**
     * 插件上下文缓存
     * 
     * @type {PluginContext}
     * @static
     * @memberof Activator
     */
    static context = null;
    constructor() {
        this.start = this.start.bind(this);
        this.stop = this.stop.bind(this);
        this.serviceChangedListener = this.serviceChangedListener.bind(this);
        this.extensionChangedListener = this.extensionChangedListener.bind(this);
    }

    /**
     * 插件入口
     * 
     * @param {PluginContext} context 插件上下文
     * @memberof Activator
     */
    start(context) {
        Activator.context = context;
        Activator.context.addServiceChangedListener(this.serviceChangedListener);
        Activator.context.addExtensionChangedListener(this.extensionChangedListener);
        log.logger.info(`INFO: The plugin ${context.plugin.id} is started.`);
    }

    /**
     * 服务监听器
     * 
     * @param {string} name 服务名称
     * @param {ServiceAction} action 服务变化活动
     * @memberof Activator
     */
    serviceChangedListener(name, action) {
        if (name === 'myService' && action === ServiceAction.ADDED) {
            let myService = Activator.context.getDefaultService(name);
            if (myService) {
                log.logger.info(`Get the myService instance successfully.`);
            }
        } else if (action === ServiceAction.REMOVED) {
            log.logger.info(`The service ${name} is removed.`);
        }
    }

    /**
     * 扩展变更监听器
     * 
     * @param {Extension} extension 扩展对象
     * @param {ExtensionAction} action 扩展对象变化活动
     * @memberof Activator
     */
    extensionChangedListener(extension, action) {
        if (action === ExtensionAction.ADDED) {
            log.logger.info(`The extension ${extension.id} is added.`);
            let extensions = Activator.context.getExtensions('myExtension');
            log.logger.info(`The extension count is ${extensions.size}.`);
        }

        if (action === ExtensionAction.REMOVED) {
            log.logger.info(`The extension ${extension.id} is removed.`);
        }
    }

    /**
     * 插件出口
     * 
     * @param {PluginContext} context 插件上下文
     * @memberof Activator
     */
    stop(context) {
        Activator.context = null;
        log.logger.info(`INFO: The plugin ${context.plugin.id} is stopped.`);
    }
}</code></pre><p>Then building another plugin as below.</p>
<pre class="prettyprint source lang-js"><code>// 1 plugin.config
{
    &quot;id&quot;: &quot;demoPlugin2&quot;,
    &quot;name&quot;: &quot;demoPlugin2Test&quot;,
    &quot;description&quot;: &quot;The demo plugin2.&quot;,
    &quot;version&quot;: &quot;1.0.1&quot;,
    &quot;startLevel&quot;: 5,
    &quot;initializedState&quot;: &quot;active&quot;,
    &quot;activator&quot;: &quot;PluginActivator.js&quot;,
    &quot;dependencies&quot;: [{
        &quot;id&quot;: &quot;demoPlugin&quot;,
        &quot;version&quot;: &quot;1.0.0&quot;
    }],
    &quot;services&quot;: [{
        &quot;name&quot;: &quot;myService&quot;,
        &quot;service&quot;: &quot;MyService.js&quot;,
        &quot;properties&quot;: {
            &quot;vendor&quot;: &quot;lorry&quot;
        }
    }],
    &quot;extensions&quot;: [{
        &quot;id&quot;: &quot;myExtension&quot;,
        &quot;data&quot;: {
            &quot;extensionData&quot;: &quot;lorry&quot;
        }
    }, {
        &quot;id&quot;: &quot;myExtension2&quot;,
        &quot;data&quot;: {
            &quot;extensionData&quot;: &quot;lorry2&quot;
        }
    }]
}
// 2 MyService.js
export default class MyService {

}
// 3 PluginActivator.js
import { ServiceAction, PluginContext, Plugin, log } from 'minimajs';

export default class PluginActivator {
    constructor() {
        this.start = this.start.bind(this);
        this.stop = this.stop.bind(this);
        this.serviceChanged = this.serviceChanged.bind(this);
    }

    /**
     * 启动插件
     * 
     * @param {PluginContext} context 插件上下文
     * @memberof PluginActivator
     */
    start(context) {
        log.logger.info(`INFO: The plugin ${context.plugin.id} is started.`);
        context.addServiceChangedListener(this.serviceChangedListener);
    }

    /**
     * 服务监听
     * 
     * @param {string} name 服务名称
     * @param {ServiceAction} action 服务活动
     * @memberof PluginActivator
     */
    serviceChangedListener(name, action) {
        if (action === ServiceAction.ADDED) {
            log.logger.info(`Service ${name} is register.`);
        } else {
            log.logger.info(`Service ${name} is unregister.`);
        }
    }

    /**
     * 停止插件
     * 
     * @param {PluginContext} context 插件上下文
     * @memberof PluginActivator
     */
    stop(context) {
        log.logger.info(`INFO: The plugin ${context.plugin.id} is stopped.`);
    }
}</code></pre><p>After starting the framework, we can see the logs as below.</p>
<pre class="prettyprint source lang-js"><code>[2017-07-30 16:14:53.128] [INFO] console - Starting the plugins with active initializedState.
[2017-07-30 16:14:53.129] [INFO] console - The plugin demoPlugin is starting.
[2017-07-30 16:14:53.132] [INFO] console - INFO: The plugin demoPlugin is started.
[2017-07-30 16:14:53.132] [INFO] console - The plugin demoPlugin is active.
[2017-07-30 16:14:53.133] [INFO] console - The plugin demoPlugin2 is starting.
[2017-07-30 16:14:53.135] [INFO] console - INFO: The plugin demoPlugin2 is started.
[2017-07-30 16:14:53.137] [INFO] console - Get the myService instance successfully.
[2017-07-30 16:14:53.137] [INFO] console - Service myService is register.
[2017-07-30 16:14:53.139] [INFO] console - The extension myExtension is added.
[2017-07-30 16:14:53.140] [INFO] console - The extension count is 1.
[2017-07-30 16:14:53.141] [INFO] console - The extension myExtension2 is added.
[2017-07-30 16:14:53.141] [INFO] console - The extension count is 1.
[2017-07-30 16:14:53.142] [INFO] console - The plugin demoPlugin2 is active.
[2017-07-30 16:14:53.143] [INFO] console - The plugins with active initializedState are started.
[2017-07-30 16:14:53.144] [INFO] console - Stopping all plugins.
[2017-07-30 16:14:53.145] [INFO] console - The plugin demoPlugin is stopping.
[2017-07-30 16:14:53.146] [INFO] console - INFO: The plugin demoPlugin is stopped.
[2017-07-30 16:14:53.147] [INFO] console - The plugin demoPlugin is stopped.
[2017-07-30 16:14:53.147] [INFO] console - The plugin demoPlugin2 is stopping.
[2017-07-30 16:14:53.148] [INFO] console - INFO: The plugin demoPlugin2 is stopped.
[2017-07-30 16:14:53.148] [INFO] console - The plugin demoPlugin2 is stopped.
[2017-07-30 16:14:53.148] [INFO] console - All plugins are stopped.</code></pre><h2>About</h2><h3>Contributing</h3><p>For bugs and feature requests, <a href="mailto:23171532@qq.com">please contact me</a>.</p>
<h3>Author</h3><p><strong>Lorry Chen</strong></p>
<p>Have 10 years on plugin framework researching.</p>
<h3>License</h3><p>Copyright © 2017, [Lorry Chen].</p>
<hr>
<p><em>This file was generated by <a href="https://github.com/verbose/verb-generate-readme">verb-generate-readme</a>, v0.6.0, on July 02, 2017.</em></p></article>
    </section>






</div>

<br class="clear">

<footer>
    Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Wed Oct 18 2017 23:16:27 GMT+0800 (CST) using the Minami theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>